#include "idt.h"
#include "system.h"

struct idt_entry idt[256];
struct idt_descriptor idtd;

char * exceptions[32] = {
 	"Division By Zero",
	"Debug",
	"Non Maskable Interrupt",
	"Breakpoint",
	"Into Detected Overflow",
	"Out of Bounds",
	"Invalid Opcode",
	"No Coprocessor",
	"Double Fault",
	"Coprocessor Segment Overrun",
	"Bad TSS",
	"Segment Not Present",
	"Stack Fault",
	"General Protection Fault",
	"Page Fault",
	"Unknown Interrupt",
	"Coprocessor Fault",
	"Alignment Check (486+)",
	"Machine Check (Pentium/586+)",
	"Reserved",
	"Reserved",
	"Reserved",
	"Reserved",
	"Reserved",
	"Reserved",
	"Reserved",
	"Reserved",
	"Reserved",
	"Reserved",
	"Reserved",
	"Reserved",
	"Reserved"};

extern void divzero();

extern void idt_init(){
	idtd.limit = (sizeof(struct idt_entry)*256) - 1;
	idtd.base = (unsigned)&idt;

	memset((unsigned char*)&idt, 0, sizeof(struct idt_entry)*256);

	install_isr(0, (unsigned)isr0, 0x08, 0x8E);
	install_isr(1, (unsigned)isr1, 0x08, 0x8E);
	install_isr(2, (unsigned)isr2, 0x08, 0x8E);
	install_isr(3, (unsigned)isr3, 0x08, 0x8E);
	install_isr(4, (unsigned)isr4, 0x08, 0x8E);
	install_isr(5, (unsigned)isr5, 0x08, 0x8E);
	install_isr(6, (unsigned)isr6, 0x08, 0x8E);
	install_isr(7, (unsigned)isr7, 0x08, 0x8E);
	install_isr(8, (unsigned)isr8, 0x08, 0x8E);
	install_isr(9, (unsigned)isr9, 0x08, 0x8E);
	install_isr(10, (unsigned)isr10, 0x08, 0x8E);
	install_isr(11, (unsigned)isr11, 0x08, 0x8E);
	install_isr(12, (unsigned)isr12, 0x08, 0x8E);
	install_isr(13, (unsigned)isr13, 0x08, 0x8E);
	install_isr(14, (unsigned)isr14, 0x08, 0x8E);
	install_isr(15, (unsigned)isr15, 0x08, 0x8E);
	install_isr(16, (unsigned)isr16, 0x08, 0x8E);
	install_isr(17, (unsigned)isr17, 0x08, 0x8E);
	install_isr(18, (unsigned)isr18, 0x08, 0x8E);
	install_isr(19, (unsigned)isr19, 0x08, 0x8E);
	install_isr(20, (unsigned)isr20, 0x08, 0x8E);
	install_isr(21, (unsigned)isr21, 0x08, 0x8E);
	install_isr(22, (unsigned)isr22, 0x08, 0x8E);
	install_isr(23, (unsigned)isr23, 0x08, 0x8E);
	install_isr(24, (unsigned)isr24, 0x08, 0x8E);
	install_isr(25, (unsigned)isr25, 0x08, 0x8E);
	install_isr(26, (unsigned)isr26, 0x08, 0x8E);
	install_isr(27, (unsigned)isr27, 0x08, 0x8E);
	install_isr(28, (unsigned)isr28, 0x08, 0x8E);
	install_isr(29, (unsigned)isr29, 0x08, 0x8E);
	install_isr(30, (unsigned)isr30, 0x08, 0x8E);
	install_isr(31, (unsigned)isr31, 0x08, 0x8E);

	set_idt();	
}

extern void install_isr(unsigned short entry, unsigned long offset, unsigned short selector, unsigned char attributes){
	idt[entry].offset1 = offset;
	idt[entry].offset2 = (offset >> 16);
	idt[entry].zero = 0;
	idt[entry].selector = selector;
	idt[entry].attributes = attributes;
}

void isr_handler(struct regs *r){
	puts(exceptions[r->int_no]);
 	puts(" Exception. System Halted!\n");

	for(;;);
}
